﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace LaunchPad.Core.Controls.Tracks
{
    public partial class TimeControl : AudioTimeControlBase
    {
        private static readonly SolidColorBrush LargeTickBrush = new SolidColorBrush(Colors.Black);
        private static readonly SolidColorBrush SmallTickBrush = new SolidColorBrush(Colors.Gray);
        private static readonly TimeSpan LabelInterval = TimeSpan.FromSeconds(10);
        private static readonly TimeSpan LargeTickInterval = TimeSpan.FromSeconds(5);
        private static readonly TimeSpan SmallTickInterval = TimeSpan.FromSeconds(1);

        public TimeControl()
        {
            InitializeComponent();
            SizeChanged += TimeControlSizeChanged;
        }

        private void TimeControlSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (e.WidthChanged)
                UpdateTicks();
        }

        protected override void OnTrackChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateTicks();
        }

        protected override void OnZoomFactorChanged(DependencyPropertyChangedEventArgs e)
        {
            UpdateTicks();
        }

        private void UpdateTicks()
        {
            timeCanvas.Children.Clear();

            /* Large Ticks */
            double largeTicks = Length.TotalSeconds/LargeTickInterval.TotalSeconds;
            for (double i = 0; i < largeTicks; i++)
            {
                TimeSpan time = TimeSpan.FromSeconds(LargeTickInterval.TotalSeconds*i);
                AddLargeTick(time);
            }

            /* Small Ticks */
            double smallTicks = Length.TotalSeconds/SmallTickInterval.TotalSeconds;
            for (double i = 0; i < smallTicks; i++)
            {
                AddSmallTick(TimeSpan.FromSeconds(SmallTickInterval.TotalSeconds*i));
            }

            /* Labels */
            double labels = Length.TotalSeconds/LabelInterval.TotalSeconds;
            for (double i = 0; i < labels; i++)
            {
                TimeSpan time = TimeSpan.FromSeconds(LabelInterval.TotalSeconds*i);
                AddLabel(time);
            }

            InvalidateMeasure();
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Size size = base.MeasureOverride(constraint);
            size.Width = AudioWidth;
            return size;
        }

        private void AddLargeTick(TimeSpan time)
        {
            double pos = ConvertFromTime(time);

            var line = new Line
                {
                    Stroke = LargeTickBrush,
                    StrokeThickness = 1,
                    X1 = pos,
                    X2 = pos,
                    Y1 = 10,
                    Y2 = ActualHeight
                };

            timeCanvas.Children.Add(line);
        }

        private void AddSmallTick(TimeSpan time)
        {
            double pos = ConvertFromTime(time);

            var line = new Line
                {
                    Stroke = SmallTickBrush,
                    StrokeThickness = 1,
                    X1 = pos,
                    X2 = pos,
                    Y1 = 10,
                    Y2 = ActualHeight
                };

            timeCanvas.Children.Add(line);
        }

        private void AddLabel(TimeSpan time)
        {
            double pos = ConvertFromTime(time);

            var label = new TextBlock {TextAlignment = TextAlignment.Center, Text = time.ToString("hh\\:mm\\:ss")};

            label.SetValue(Canvas.LeftProperty, pos);
            label.FontSize = 9;

            timeCanvas.Children.Add(label);
        }
    }
}